﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.Linq;

namespace Nirvana
{
    [CustomPropertyDrawer(typeof(EnumLabelAttribute))]
    public sealed class EnumLabelPropertyDrawer : PropertyDrawer
    {
        Dictionary<string, string> labelDic = new Dictionary<string, string>();
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            if(property.propertyType != SerializedPropertyType.Enum)
            {
                return;
            }

            EnumLabelAttribute enumlabel = base.attribute as EnumLabelAttribute;

            this.FindAllLabel(property, property.enumNames);
            EditorGUI.BeginChangeCheck();
            //映射enum到对应的label注释
            var enumNames = property.enumNames.Where(p => this.labelDic.ContainsKey(p)).Select(p=> this.labelDic[p]).ToArray<string>();

            var enumOrders = SetOrders(enumlabel.EnumOrder);
            if(enumOrders.Length != enumNames.Length)
            {
                enumOrders = new int[enumNames.Length];
                for (int i = 0; i < enumOrders.Length; i++)
                {
                    enumOrders[i] = i;
                }
            }
            string[] tempEnumNames = new string[enumNames.Length];
            tempEnumNames[0] = enumNames[0];
            for (int j = 0; j < enumNames.Length; j++)
            {
                tempEnumNames[j] = enumNames[enumOrders[j]];
            }

            int num = -1;
            for (int k = 0; k < enumOrders.Length; k++)
            {
                if (enumOrders[k] == property.enumValueIndex)
                {
                    num = k;
                    break;
                }
            }
            if (num == -1 && property.enumValueIndex != -1)
            {
                EditorGUI.PropertyField(position, property, new GUIContent(label.text + " (sorting error)"));
                EditorGUI.EndProperty();
                return;
            }

            string displayName = property.displayName;
           
            if (!string.IsNullOrEmpty(enumlabel.Label))
            {
                displayName = enumlabel.Label;
            }
          
            num = EditorGUI.Popup(position, displayName, num, tempEnumNames);
            if (EditorGUI.EndChangeCheck() && num >= 0)
            {
                property.enumValueIndex = enumOrders[num];
            }
        }
        private void FindAllLabel(SerializedProperty prop, string[] labels)
        {
            var enumAttributes = base.fieldInfo.GetCustomAttributes(typeof(EnumLabelAttribute), false);
            foreach(var p in enumAttributes)
            {
                Type fieldType = base.fieldInfo.FieldType;
                foreach(var t in labels)
                {
                    var field = fieldType.GetField(t);
                    if(field != null)
                    {
                        var e = (EnumLabelAttribute[])field.GetCustomAttributes(p.GetType(), false);
                        if (!this.labelDic.ContainsKey(t))
                        {
                            foreach (var l in e)
                            {
                                this.labelDic.Add(t, l.Label);
                            }
                        }
                    }
                }
            }


        }

        private int[] SetOrders(int[] enumOrders)
        {
            int[] curEnums = new int[enumOrders.Length];
            for(int i = 0; i < enumOrders.Length; ++i)
            {
                int count = 0;
                for(int j = 0; j < enumOrders.Length; ++j)
                {
                    if (enumOrders[i] > enumOrders[j]) count++;
                }
                curEnums[i] = count;
            }

            return curEnums;
        }

    }



}
